package com.igeek.boot.aop;

import com.igeek.boot.anno.WMSLoganno;
import com.igeek.boot.entity.User;
import com.igeek.boot.entity.WmsLog;
import com.igeek.boot.result.Result;
import com.igeek.boot.service.IWmsLogService;
import com.igeek.boot.utils.JwtHelper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @package com.igeek.boot.aop
 * @Description aop添加日志信息
 * @Author LittlePunk [296526219@qq.ccom]
 * @Version 2022.1
 * @Date 2024/1/8 16:26
 */
@Component
@Slf4j
@Aspect
public class WMSLogAspect {

    //获得当前请求对象
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private IWmsLogService wmsLogService;

    //切点表达式  针对添加了WMSLog的类进行通知

    @Pointcut("@annotation(com.igeek.boot.anno.WMSLoganno)")
    public void pt(){}

    //开启环绕通知
    @Around("pt()")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取当前的时间戳
        LocalDateTime operateTime = LocalDateTime.now();
        long begin = System.currentTimeMillis();
        //执行方法
        Result result = (Result) joinPoint.proceed();
        long end = System.currentTimeMillis();
        //保存日志信息
        recordLog(joinPoint,operateTime,end-begin,result);
        return result;
    }

    private void recordLog(ProceedingJoinPoint joinPoint, LocalDateTime operateTime, long time,Result result) {
        //提取注解的内容
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        WMSLoganno wmsLoganno = signature.getMethod().getAnnotation(WMSLoganno.class);
        //获取模块名和操作信息
        String module = wmsLoganno.module();
        String operation = wmsLoganno.operation();

        //获取到操作的方法名和参数信息
        //操作类名
        String className = joinPoint.getTarget().getClass().getName();
        //操作方法名
        String methodName = joinPoint.getSignature().getName();
        //操作参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

        //获取到操作人的信息
        String token = request.getHeader("token");
        String userName = JwtHelper.getUserName(token);

        //进行封装操作
        WmsLog wmsLog = new WmsLog(null, module, operation, className + "-" + methodName
                , methodParams, userName, operateTime, result.isFlag() ? 1 : 0, result.getMessage(), (int) time);
        //存入日志中
        log.info("wmsLog:{}",wmsLog);
        wmsLogService.save(wmsLog);

    }

}
